<?php

namespace app\api\logic;

use app\api\cache\Marketing;
use app\api\cache\MemberCache;
use app\api\consDir\ErrorConst;
use app\api\consDir\OrderPrefixConst;
use app\api\consDir\SandConst;
use app\api\controller\Card;
use app\api\services\MemberService;
use app\api\services\OrderService;
use app\api\services\PayService;
use app\api\services\RabbitMqService;
use app\api\services\SandService;
use app\api\services\ServiceCenterService;
use app\api\services\ShopService;
use app\common\libs\Singleton;
use app\common\models\Card\CardUser;
use app\common\models\Order\Order;
use app\common\models\Order\OrderGoods;
use app\common\models\Order\OrderPay;
use app\common\models\Order\OrderShop;
use app\common\models\Order\ServiceOrder;
use app\common\models\Service\Service;
use app\common\models\Service\ServiceGoods;
use app\common\models\Service\ServicesOrder;
use app\common\models\Service\ServicesOrderItemLog;
use app\common\models\Service\ServicesUser;
use app\common\models\Service\ServiceTag;
use app\common\models\Shop\Goods;
use app\common\models\Shop\Shop;
use app\common\utils\CommonUtil;
use app\common\utils\RedLock;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

class ServiceLogic extends BaseLogic
{
    use Singleton;

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function serviceList($page, $pageSize): array
    {
        return ServiceCenterService::getInstance()->serviceList($page, $pageSize, $this->userinfo->id);
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function serviceTaskList($page, $pageSize, $goodsId): array
    {
        if(empty($goodsId)){
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '商品ID不能为空');
        }
        $applyType = Goods::getInstance()->where('id',$goodsId)->value('apply_type');
        if($applyType == 0){
            $where = [
                ['deleted', '=', 0],
                ['status','=',0],
            ];
            $list = Service::getInstance()
                ->where($where)
                ->field('*,id as service_id')
                ->page($page, $pageSize)
                ->select();
        }else{
            $where = [
                ['a.goods_id', '=', $goodsId],
                ['a.deleted', '=', 0],
                ['s.status','=',0],
                ['s.deleted','=',0]
            ];
            $list = ServiceGoods::getInstance()
                ->alias('a')
                ->leftJoin('service s', 'a.service_id=s.id')
                ->field('a.*,s.service_province,s.service_city,s.service_country,s.detail_address,s.name,s.contact_name,s.opening_hours')
                ->where($where)
                ->page($page, $pageSize)
                ->order('id desc')
                ->select();
        }

        if (empty($list)) {
            return [];
        }
        foreach ($list as &$v) {
            $v['allAddress'] = $v['service_province'] . $v['service_city'] . $v['service_country'] . $v['detail_address'];
        }
        return $list->toArray();
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function check($orderNo,$serviceId): bool
    {
        if(empty($orderNo)){
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '商品ID不能为空');
        }
        if(empty($serviceId)){
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '服务中心ID不能为空');
        }
        $where = [
            ['order_no', '=', $orderNo],
            ['service_id','=',$serviceId]
        ];
        $order = Order::getInstance()->where($where)->find();
        if (empty($order)) {
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '订单不存在');
        }
        $where = [
            ['id', '=', $serviceId],
            ['user_id', '=', $this->userinfo->id],
            ['deleted', '=', 0]
        ];
        $service = Service::getInstance()->where($where)->find();
        if (empty($service)) {
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '该服务中心暂无权限');
        }
        //0待支付 1待发货 2待收款 3已收货 4已完成 5退款中 6退款成功 7取消 8超时取消 9待退货
        if ($order['status'] != 10) {
            CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, ErrorConst::ORDER_STATUS_ERROR_MSG);
        }
        $task = OrderService::getInstance()->taskOrder($order, $this->userinfo->id);
        if (empty($task)) {
            CommonUtil::throwException(ErrorConst::SYSTEM_ERROR, ErrorConst::SYSTEM_ERROR_MSG);
        }
        // 检查会员等级升级
        try {
            \app\api\services\UserLevelService::getInstance()->checkUpgrade(
                $this->userinfo->id
            );
        } catch (\Exception $e) {
            \think\facade\Log::error($e->getMessage());
        }
        return true;
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function orderDetail($orderNo,$serviceId): array
    {
        if(empty($orderNo)){
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, ErrorConst::PARAM_ERROR_MSG);
        }
        if(empty($serviceId)){
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '服务中心ID不能为空');
        }
        $order = ServiceCenterService::getInstance()->orderDetail($orderNo,$serviceId,$this->userinfo->id);
        if(empty($order)){
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '订单不存在');
        }
        return $order;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function checkList($page, $pageSize, $serviceId): array
    {
        return ServiceCenterService::getInstance()->checkList($this->userinfo->id,$page,$pageSize,$serviceId);
    }

    /**
     * @throws DbException
     */
    public function show(): array
    {
        $where = [
            ['user_id','=',$this->userinfo->id],
            ['deleted','=',0]
        ];
        $count = Service::getInstance()->where($where)->count();
        return ['status' => $count > 0 ? 1 : 0];
    }

    /**
     * 附近服务中心列表
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function serviceNearbyList($page, $pageSize, $lng, $lat): array
    {
        return ServiceCenterService::getInstance()->serviceNearbyList($page, $pageSize,$lng,$lat);
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function serviceDetail($id): array
    {
        $ret = Service::getInstance()->where('id',$id)->find();
        if(empty($ret)){
            return [];
        }
        $ret['deductionRate'] = ServiceCenterService::getInstance()->getDeductionRate($id);
        $ret['allAddress'] = $ret['serviceProvince'].$ret['serviceCity'].$ret['serviceCountry'].$ret['detailAddress'];
        $ret['tagList'] = ServiceTag::getInstance()->where('id','in',$ret['tag'])->field('id,name')->select();
        return $ret->toArray();
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function orderList($page, $pageSize, $serviceId, $orderNo, $orderType): array
    {
        return ServiceCenterService::getInstance()->orderList($page, $pageSize, $serviceId, $orderNo, $orderType,$this->userinfo->id);
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function createOrder($servicesId,$deduction): array
    {
        if (empty($servicesId)) {
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, ErrorConst::PARAM_ERROR_MSG);
        }
        $where = [
            ['id', '=', $servicesId],
            ['deleted', '=', 0],
        ];
        $servicesUser = ServicesUser::getInstance()->where($where)->find();
        if(empty($servicesUser)){
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, '服务不存在');
        }

        $orderNo = getNo('SE');
        $ret = ServiceCenterService::getInstance()->createOrder($this->userinfo->id, $servicesUser, $orderNo, $deduction);
        if ($ret !== true) {
            CommonUtil::throwException(ErrorConst::SYSTEM_ERROR, $ret);
        }

        $expireAt = date('Y-m-d H:i:s', strtotime('+5 minutes'));
        return ['orderNo' => $orderNo, 'expireAt' => $expireAt,'payPrice' => $servicesUser['sell_price']];
    }

    public function servicesUserList($page, $pageSize, $serviceId): array
    {
        $where = [
            ['deleted','=',0],
            ['up_down_status','=',1],
            ['service_id','=',$serviceId]
        ];
        $list = ServicesUser::getInstance()->where($where)->page($page,$pageSize)->select();
        $config = Marketing::getKeyData('service', 'service_config');
        $where = [
            ['user_id','=',$this->userinfo->id],
            ['card_type','=',0],
            ['expire_at','>',date('Y-m-d H:i:s')]
        ];
        $cardUser = CardUser::getInstance()->where($where)->order('card_time_type desc')->find();
        foreach($list as &$v){
            $v['discountPrice'] = $v['sellPrice'];
            if(isset($config['discount_rate']) && $config['discount_rate'] > 0){
                $v['discountPrice'] = bcmul($v['sellPrice'],$config['discount_rate']*0.01,2);
            }
            if($cardUser){
                $rate = \app\common\models\Card\Card::getInstance()->where('id',$cardUser['cardId'])->value('rate') ?: 0;
                if($rate > 0){
                    $v['discountPrice'] = bcmul($v['sellPrice'],$rate*0.01,2);
                }
            }
        }
        return !empty($list) ? $list->toArray() : [];
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function payOrder($orderNo, $payType, $payPassword, $paySubType): array
    {
        if ( ! RedLock::getInstance()->lock('servicePayOrder_' . $this->userinfo->id, 3)) {
            CommonUtil::throwException(ErrorConst::FREQUENT_ERROR, ErrorConst::FREQUENT_ERROR_MSG);
        }

        if ($payType == 3) {
            $account = MemberService::getInstance()->account($this->userinfo->id);
            if (empty($account)) {
                CommonUtil::throwException(ErrorConst::NO_PAY_PASSWORD_ERROR, ErrorConst::NO_PAY_PASSWORD_ERROR_MSG);
            }

            //验证支付密码
            if ($account['payPwd'] != $payPassword) {
                CommonUtil::throwException(ErrorConst::PAY_PASSWORD_ERROR, ErrorConst::PAY_PASSWORD_ERROR_MSG);
            }
        }

        $order = ServicesOrder::getInstance()->where('order_no',$orderNo)->find();
        if (empty($order)) {
            CommonUtil::throwException(ErrorConst::NO_ORDER_ERROR, ErrorConst::NO_ORDER_ERROR_MSG);
        }
        if ($order['status'] != 0) {
            CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, ErrorConst::ORDER_STATUS_ERROR_MSG);
        }

        if($order['deduction'] > 0){
            $finance = MemberService::getInstance()->finance($order['userId']);
            if($finance['deduction'] < $order['deduction']){
                CommonUtil::throwException(ErrorConst::PARAM_ERROR, '平台抵扣券不足');
            }
        }

        $isBalance = 0;

        ServicesOrder::getInstance()->where('order_no', $orderNo)->update([
            'pay_type' => $payType,
        ]);
        $payInfo = PayService::getInstance()->payOrder($this->userinfo->id, $order, $payType);
        if ($payType == 3) {
            $userBalance = MemberService::getInstance()->finance($this->userinfo->id);
            if ($payInfo['pay_price'] > $userBalance['amount']) {
                CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '余额不足');
            }
            $isBalance = 1;
        }

        $userInfo = MemberService::getInstance()->getUserInfo($this->userinfo->id);
        if ($payType == 3) {
            //余额全付
            $info = [
                'pay_status' => 3,
                'pay_no' => $payInfo['pay_no'],
                'money' => $payInfo['pay_price'],
                'trade_no' => '',
                'receipt_data' => '',
            ];
            $event["exchange"] = config('rabbitmq.order_callback_queue');
            RabbitMqService::send($event, $info);
            $pay = [];
        } elseif ($payType == 4) {
            $pay = SandLogic::getInstance()->orderCreate($this->userinfo->id, $payInfo['pay_price'], $payInfo['pay_no']);
        } elseif ($payType == 5) {
            $pay = SandLogic::getInstance()->orderCreateScan($payInfo['pay_price'], $payInfo['pay_no']);
        } else {
            $pay = PayService::getInstance()->toPay($payInfo, $userInfo, $payType, $paySubType);
        }
        return ['payInfo' => $pay, 'isBalance' => $isBalance];
    }

    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     */
    public function serviceOrderList($page, $pageSize,$status): array
    {
        $where = [
            ['deleted','=',0],
            ['user_id','=',$this->userinfo->id]
        ];
        if(is_numeric($status)){
            $where[] = ['status','=',$status];
        }
        $list = ServiceOrder::getInstance()->where($where)->order('id desc')->page($page,$pageSize)->select();
        foreach($list as &$v){
            if($v['type'] == 1){
                $v['coverImg'] = Service::getInstance()->where('id',$v['serviceId'])->value('cover_img') ?: '';
            }
        }
        return !empty($list) ? $list->toArray() : [];
    }

    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     */
    public function serviceOrderDetail($orderNo): array
    {
        $list = ServiceOrder::getInstance()->where('order_no',$orderNo)->find();
        if(empty($list)){
            CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '订单不存在');
        }
        $service = Service::getInstance()->where('id',$list['serviceId'])->find();
        $list['serviceName'] = $service['name'] ?? '';
        if($list['type'] == 1){
            $list['coverImg'] = $service['coverImg'] ?? '';
        }
        //card_type 卡类型 0标准卡 1特殊卡
        $where = [
            ['user_id','=',$this->userinfo->id],
            ['card_type','=',0],
            ['expire_at','>',date('Y-m-d H:i:s')]
        ];
        $cardUser = CardUser::getInstance()->where($where)->order('card_time_type desc')->find();
        $list['discountPrice1'] = $list['price'];
        $config = Marketing::getKeyData('service', 'service_config');
        if(empty($cardUser) && isset($config['discount_rate']) && $config['discount_rate'] > 0){
            $list['discountPrice1'] = bcmul($list['price'],$config['discount_rate']*0.01,2);
        }
        if($cardUser){
            $rate = \app\common\models\Card\Card::getInstance()->where('id',$cardUser['cardId'])->value('rate') ?: 0;
            if($rate > 0){
                $list['discountPrice1'] = bcmul($list['price'],$rate*0.01,2);
            }
        }
        return !empty($list) ? $list->toArray() : [];
    }

    public function createPromptOrder($price,$serviceId,$deduction = 0): array
    {
        if(empty($price)){
            CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '金额不能为空');
        }
        if($price <= 0){
            CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '金额要大于0');
        }
        if(empty($serviceId)){
            CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, 'serviceId不能为空');
        }

        if($deduction > 0){
            $config = Marketing::getKeyData('marketing', 'deduction');
            if(!isset($config['service_status']) || $config['service_status'] != 1){
                CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '未开启平台抵扣券');
            }
            $deductionRate = ServiceCenterService::getInstance()->getDeductionRate($serviceId);
            if($deductionRate > 0){
                $deductionMoney = bcmul($price,$deductionRate*0.01,2);
                if($deduction > $deductionMoney){
                    CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '平台抵扣券错误');
                }
            }
        }


        $orderNo = getNo('SE');
        $order = ServiceCenterService::getInstance()->createPromptOrder($price,$serviceId,$this->userinfo->id,$orderNo,$deduction);
        if ( ! $order) {
            CommonUtil::throwException(ErrorConst::SYSTEM_ERROR, ErrorConst::SYSTEM_ERROR_MSG);
        }
        $order = ServicesOrder::getInstance()->where('order_no',$orderNo)->find();
        return !empty($order) ? $order->toArray() : [];
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function servicesUser($id): array
    {
        $ret = ServicesUser::getInstance()->where('id',$id)->find();
        //card_type 卡类型 0标准卡 1特殊卡
        $where = [
            ['user_id','=',$this->userinfo->id],
            ['card_type','=',0],
            ['expire_at','>',date('Y-m-d H:i:s')]
        ];
        $cardUser = CardUser::getInstance()->where($where)->order('card_time_type desc')->find();
        $ret['discountPrice'] = $ret['sellPrice'];
        $config = Marketing::getKeyData('service', 'service_config');
        if(isset($config['discount_rate']) && $config['discount_rate'] > 0){
            $ret['discountPrice'] = bcmul($ret['sellPrice'],$config['discount_rate']*0.01,2);
        }
        if($cardUser){
            $rate = \app\common\models\Card\Card::getInstance()->where('id',$cardUser['cardId'])->value('rate') ?: 0;
            if($rate > 0){
                $ret['discountPrice'] = bcmul($ret['sellPrice'],$rate*0.01,2);
            }
        }

        $deductionRate = ServiceCenterService::getInstance()->getServiceDeductionRate($ret);
        $ret['deductionRate'] = $deductionRate;
        return !empty($ret) ? $ret->toArray() : [];
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function servicesOrderItemLog($orderNo,$page,$pageSize): array
    {
        $where = [
            ['user_id','=',$this->userinfo->id]
        ];
        if(!empty($orderNo)){
            $where[] = ['order_no','=',$orderNo];
        }
        $list = ServicesOrderItemLog::getInstance()->where($where)->page($page,$pageSize)->order('id desc')->select();
        foreach($list as &$v){
            $v['address'] = $v['service_province'].$v['service_city'].$v['service_country'].$v['service_street'].$v['service_comm'].$v['detailAddress'];
            $v['userName'] = MemberCache::getInfo($v['userId'],'user_name');
            $v['checkUserName'] = MemberCache::getInfo($v['checkUserId'],'user_name');
        }
        $rows =  !empty($list) ? $list->toArray() : [];
        return ['rows' => $rows];
    }

}